#!/usr/bin/python -O
import string
import re
import os
import sys
import shutil
import traceback

#
# printcapInfo class
#
class printcapInfo:
	"""
		type       - type of printcap found
		header     - header line(s) before a printer entry
		footer     - footer lines(s) after a printer entry
		def_space  - space in front of name if not default
		search_del - string(s) to search for to delete entry
		search_add - string(s) to search for to insert before
		last_line  - string(s) to add after the entry
	"""

	def __init__ (self):
		self.type = ""
		self.header = []
		self.footer = []
		self.def_space = ""
		self.search_del = []
		self.search_add = []
		self.last_line = []

	def __str__(self):
		return '<printcapInfo: %s %s %s %s %s %s>' % (self.header, self.footer, self.def_space,
				self.search_del, self.search_add, self.last_line)

#
# Usage print out function
#
def usage():
	print "Usage: " + sys.argv[0] + " -a printer ip_address"
	print "       " + sys.argv[0] + " -d printer"

#
# Attempt to determine what type of printcap file we are dealing with
# and set the insert and delete search patterns, header lines and
# end lines as appropriate
#
def get_printcap_info(lines, printer_name):
	pInfo = printcapInfo()
	found = 0
	for line in lines:
		if ( string.find(line, "printcap.local") != -1 ):
		# LPRng printcap file
			pInfo.type = "LPRng"
#			pInfo.footer.append("\n")
#			pInfo.def_space = " "
#			pInfo.search_del.append(printer_name)
#			pInfo.search_add.append("printcap.local")
#			pInfo.search_add.append("#############")
#			pInfo.last_line.append("^\n$")
			found = 1
#			print "LPRng"
		elif ( string.find(line, "printtool") != -1 ):
		# Redhat 6.2 printcap file
			pInfo.type = "rh62"
			pInfo.header.append("##PRINTTOOL3## REMOTE POSTSCRIPT 600x600 letter {} PostScript Default {}\n")
			pInfo.search_del.append(printer_name)
			pInfo.search_del.append("##PRINTTOOL3## REMOTE")
			pInfo.search_add.append("EOF")
			pInfo.last_line.append(":\n$")
			found = 1
#			print "lpr rh62"
		elif ( string.find(line, "BEGIN apsfilter") != -1 ):
		# SuSE printcap file
			pInfo.type = "SuSE"
			pInfo.header.append("### BEGIN apsfilter: ### " + printer_name + " ###\n")
			pInfo.header.append("#   Warning: Configured for apsfilter, do not edit the labels!\n")
			pInfo.header.append("#\n")
			pInfo.header.append("#\n")
			pInfo.footer.append("#\n")
			pInfo.footer.append("### END apsfilter: ### " + printer_name + " ###\n")
			pInfo.search_del.append(printer_name)
			pInfo.search_del.append("#")
			pInfo.search_del.append("#")
			pInfo.search_del.append("#")
			pInfo.search_del.append("### BEGIN apsfilter: ###")
			pInfo.search_add.append("EOF")
			pInfo.last_line.append("### END")
			found = 1
#			print "lpr suse"
		if ( found == 1 ):
			break
	if ( found == 0 ):
	# assume Other ?? printcap file
		pInfo.type = "Other"
		pInfo.header.append("### BEGIN staircase filter: ### " + printer_name + " ###\n")
		pInfo.header.append("#   Warning: Configured for Stair case!\n")
		pInfo.header.append("#\n")
		pInfo.header.append("#\n")
		pInfo.footer.append("#\n")
		pInfo.footer.append("### END staircase filter : ### " + printer_name + " ###\n")
		pInfo.search_del.append(printer_name)
		pInfo.search_del.append("#")
		pInfo.search_del.append("#")
		pInfo.search_del.append("#")
		pInfo.search_del.append("### BEGIN staircase filter: ###")
		pInfo.search_add.append("EOF")
		pInfo.last_line.append("### END")
#		print "Other"
	return (pInfo)
#
# check the uid - if not root exit
#
if ( os.geteuid() != 0 ):
	print "You need to be root to run this!!!"
	sys.exit()
#
# check the arguments and determine if we are adding or deleting a printer
#
if ( len(sys.argv) > 2 ):
	action = None
	if ( sys.argv[1] == "-d" and len(sys.argv) == 3 ):
#		print "deleting"
		action = "Delete"
	elif ( sys.argv[1] == "-a" and len(sys.argv) == 4 ):
#		print "adding"
		action = "Adding"
	else:
		usage()
		sys.exit()
else:
	usage()
	sys.exit()

printer_name = sys.argv[2]
#
# Read in the printcap file
#
pcfile = open("/etc/printcap", "r")

lines = pcfile.readlines()
pcfile.close()

#
# Get printcap file info
#
pcapInfo = get_printcap_info(lines, printer_name)
#print pcapInfo
#
# Process an add request
#
if ( action == "Adding" ):
	ip_addr = sys.argv[3]
	if ( pcapInfo.type == "LPRng" ):
		write_list = []
		write_list.append("printconf_import required")
		db_flag = open("/opt/toshiba/tap/bin/flag_" + printer_name, "w")
		db_flag.writelines(write_list)
		db_flag.close()
		sys.exit()
	i = 0
	insert_line = 0
	for line in lines:
#		print line
		test = 0
		if ( ((string.find(line, printer_name + ":") != -1)
			or (string.find(line, printer_name + "|") != -1))
			and (string.find(line, "/" + printer_name) == -1) ):
			print "Printer " + printer_name + " already exists!!!"
			sys.exit()
		if ( (string.find(line, pcapInfo.search_add[0]) != -1) ):
#			print line
			test = 1
			count = 0
			while count + 1 < len(pcapInfo.search_add):
				count = count + 1
#				print count
#				print lines[i - count]
#				print pcapInfo.search_add[count]
				if ( string.find(lines[i - count], pcapInfo.search_add[count]) == -1 ):
#					print "clearing test"
					test = 0
			if ( test == 1 ):
				insert_line = i - count
				break
		i = i + 1
	if ( pcapInfo.search_add[0] == "EOF" ):
		insert_line = i
#
# now add the lines for the printer entry
#
	count = 0
	while ( count < len(pcapInfo.header) ):
		lines.insert(insert_line, pcapInfo.header[count])
		insert_line = insert_line + 1
		count = count + 1
	lines.insert(insert_line, pcapInfo.def_space + printer_name + ":\\\n")
	insert_line = insert_line + 1
	lines.insert(insert_line, "\t:sd=/var/spool/lpd/" + printer_name + ":\\\n")
	insert_line = insert_line + 1
	lines.insert(insert_line, "\t:mx#0:\\\n\t:sh:\\\n")
	insert_line = insert_line + 1
	lines.insert(insert_line, "\t:rm=" + ip_addr + ":\\\n")
	insert_line = insert_line + 1
	lines.insert(insert_line, "\t:rp=dssc:\\\n")
	insert_line = insert_line + 1
	lines.insert(insert_line, "\t:if=/var/spool/lpd/" + printer_name + "/filter:\n")
	insert_line = insert_line + 1
	count = 0
	while ( count < len(pcapInfo.footer) ):
		lines.insert(insert_line, pcapInfo.footer[count])
		insert_line = insert_line + 1
		count = count + 1
#
# Now add the spool directory and the required files
#
	try:
		os.mkdir("/var/spool/lpd/" + printer_name, 0755)
	except:
		pass

	
	if ( pcapInfo.type == "LPRng" ):
		try:
			shutil.copy("/usr/lib/rhs/rhs-printfilters/master-filter", "/var/spool/lpd/" + printer_name + "/filter")
		except:
			pass
	elif ( pcapInfo.type == "rh62" ):
		try:
			shutil.copy("/opt/toshiba/tap/bin/filter", "/var/spool/lpd/" + printer_name + "/filter")
		except:
			pass
	elif ( pcapInfo.type == "SuSE" ):
		try:
			shutil.copy("/opt/toshiba/tap/bin/filter", "/var/spool/lpd/" + printer_name + "/filter")
		except:
			pass
	elif ( pcapInfo.type == "Other" ):
		try:
			shutil.copy("/opt/toshiba/tap/bin/filter", "/var/spool/lpd/" + printer_name + "/filter")
		except:
			pass
#
# Process a delete request
#
elif ( action == "Delete" ):
	if ( pcapInfo.type == "LPRng" ):
		write_list = []
		write_list.append("printconf_import required")
		db_flag = open("/opt/toshiba/tap/bin/flag_" + printer_name, "w")
		db_flag.writelines(write_list)
		db_flag.close()
		sys.exit()
	i = 0
	delete_line = 0
	test = 0
	for line in lines:
		try:
			if ( ((string.find(line, pcapInfo.search_del[0] + ":") != -1)
				or (string.find(line, pcapInfo.search_del[0] + "|") != -1))
				and (string.find(line, "/" + pcapInfo.search_del[0]) == -1) ):
				test = 1
				count = 0
#				print line
				while count + 1 < len(pcapInfo.search_del):
					count = count + 1
#					print lines[i - count]
#					print pcapInfo.search_del[count]
					if ( string.find(lines[i - count], pcapInfo.search_del[count]) != 0 ):
						test = 0
				if ( test == 1 ):
					delete_line = i - count
				break
		except:
			traceback.print_exc()
			pass
		i = i + 1
	if ( test == 0 ):
		print "No such printer - " + printer_name
		sys.exit()
	while ( re.compile(pcapInfo.last_line[0]).search(lines[delete_line]) == None ):
#		print lines[delete_line]
		del lines[delete_line]
	del lines[delete_line]
#
# Now remove the spool directory
#
#	try:
	shutil.rmtree("/var/spool/lpd/" + printer_name)
#	except:
#		pass
else:
	sys.exit()
#
# save the old printcap file then
# write out the new printcap file
#
os.rename("/etc/printcap", "/etc/printcap.save")
newpc = open("/etc/printcap","w")
newpc.truncate()
newpc.writelines(lines)
newpc.close

